package com.caigou.task;

import com.caigou.bean.cms.entity.Article;
import com.caigou.bean.cms.entity.ArticleKeyword;
import com.caigou.bean.cms.entity.ArticleTitle;
import com.caigou.bean.cms.entity.EsArticle;
import com.caigou.bean.vo.KeyValueVO;
import com.caigou.mapper.cms.ArticleKeywordMapper;
import com.caigou.mapper.cms.ArticleTitleMapper;
import com.caigou.service.IEsArticleService;
import lombok.extern.slf4j.Slf4j;
import org.jsoup.Jsoup;
import org.jsoup.select.Elements;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;


@Slf4j
@Component
@Configuration      //1.主要用于标记配置类，兼备Component的效果。
@EnableScheduling   // 2.开启定时任务
public class EsArticleTask {

    @Resource
    private IEsArticleService esArticleService;
    @Value("${domain}")
    private String domain;
    @Value("${accept}")
    private boolean accept;
    @Resource
    private ArticleTitleMapper articleTitleMapper;
    @Resource
    private ArticleKeywordMapper articleKeywordMapper;


    //30秒执行一次
    @Scheduled(cron = "*/15 * * * * ?")
    public void esBidIndexTask() {
        log.info("是否执行定时任务" + accept);
        if (accept) {
            //查询文章数据
            Integer pageSize = 100;//每次查询100条文章数据
            List<Article> articleList = esArticleService.findUnIndexedArticleList(pageSize);


            if (!CollectionUtils.isEmpty(articleList)) {
                List<String> articleIds = articleList.stream().map(Article::getArticleId).collect(Collectors.toList());
                //批量查询文章内容页

                Map<String, String> stringMap = new HashMap<>();
                articleList.forEach(bean -> {
                    if (!StringUtils.isEmpty(bean.getArticleUrl())) {
                        Elements body = null;
                        try {
                            body = Jsoup.connect(bean.getArticleUrl()).get().body().getElementsByClass("container");
                            //将文章内容添加至文章字段
                            if (!CollectionUtils.isEmpty(body))
                                body.forEach(element -> {
                                    String textContent = element.getElementById("main").text();
                                    stringMap.put(bean.getArticleId(), textContent);
                                });

                        } catch (IOException e) {
                            log.info("解析发生错误,文章id={}",bean.getArticleId());
                            esArticleService.updateArticleIndexStatus(bean.getArticleId());
                            e.printStackTrace();
                        }

                    }

                });


                //批量查询文章标题列表
                List<ArticleTitle> titleByArticleIds = articleTitleMapper.findArticleTitleByArticleIds(articleIds);
                Map<String, List<ArticleTitle>> articleTitleMap = titleByArticleIds.stream().collect(Collectors.groupingBy(ArticleTitle::getArticleId));
                //批量查询文章关键词
                String[] split = articleList.stream().map(Article::getArticleKeyWord).collect(Collectors.joining(",")).split(",");
                List<String> articleKeyWordIds = Arrays.stream(split).distinct().collect(Collectors.toList());
                List<ArticleKeyword> articleKeywords = articleKeywordMapper.findArticleKeywordsByArticleIds(articleKeyWordIds);

                articleList.stream().map(bean -> {
                    EsArticle esArticle = new EsArticle();
                    BeanUtils.copyProperties(bean, esArticle);
                    esArticle.setArticleType(bean.getArticleType() != null ? bean.getArticleType().toString() : null);
                    esArticle.setArticlePromoter(Integer.parseInt(bean.getArticlePromoter()));
                    esArticle.setPublicTime(bean.getPublicTime() != null ? bean.getPublicTime() : bean.getCreateTime());
                    log.info("转换es实体:->{}",esArticle);
                    return esArticle;
                }).peek(bean -> bean.setArticleKeyWordVOS(getKeyValueVOS(articleKeywords, bean.getArticleKeyWord())))
                        .peek(bean -> bean.setArticleTitleVOS(articleTitleMap.get(bean.getArticleId())))
                        .peek(bean -> bean.setArticlePureContent(stringMap.get(bean.getArticleId())))
                        .peek(bean -> {
                            //将内文标题与列表标题共同存入标题搜索字段中
                            if (!CollectionUtils.isEmpty(bean.getArticleTitleVOS())) {
                                String collectTitle = bean.getArticleTitleVOS().stream().map(ArticleTitle::getArticleTitle)
                                        .collect(Collectors.joining(",", bean.getArticleTitle() + ",", ""));
                                bean.setSearchTitle(collectTitle);
                            } else {
                                bean.setSearchTitle(bean.getArticleTitle());
                            }
                        })
                        .forEach(bean -> {
                            log.info("保存的文章:->{}",bean);
                            EsArticle article = esArticleService.saveEsArticle(bean);
                            Integer updateNum = esArticleService.updateArticleIndexStatus(article.getArticleId());
                        });
            }
        }

        //定时清理已删除的文章




    }

    private List<KeyValueVO> getKeyValueVOS(List<ArticleKeyword> articleKeywords, String articleKeyWord) {
        if (CollectionUtils.isEmpty(articleKeywords) || StringUtils.isEmpty(articleKeyWord)) {
            return Collections.emptyList();
        }

        Map<Integer, String> articleKeywordMap = articleKeywords.stream().collect(Collectors.toMap(ArticleKeyword::getId, ArticleKeyword::getKeyword));
        String[] split = articleKeyWord.split(",");
        List<String> articleKeyWordIds = Arrays.asList(split);
        return articleKeyWordIds.stream().map(id -> {
            KeyValueVO valueVO = new KeyValueVO();
            valueVO.setValue(id);
            valueVO.setLabel(articleKeywordMap.get(Integer.parseInt(id)));
            valueVO.setDomain(domain);
            return valueVO;
        }).collect(Collectors.toList());
    }


}
